#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <gnome.h>
#include <assert.h>

#include "perror_exit.h"
#include "interface.h"
#include "monitor.h"

monitor monitors[] = {

	{
		MONITOR_TYPE_URL_WATCH,
		"URL Watch",
		"Whenever a given URL is accessed, you will be notified of the time and the site which requested the URL",
		FALSE,
		-1,
		(watch_init_url),
		{
			MONITOR_ACTION_POPUP,
			(monitor_popup),
			NULL
		},
		{
			(conf_form_url_watch),
			NULL		
		}
	},

	{
		MONITOR_TYPE_DOMAIN_WATCH,
		"Domain Watch",
		"You will be notified whenever a client whose domain contains a given domain string (i.e. .cs.rpi.edu) makes a request from your server",
		FALSE,
		-1,
		(watch_init_domain),
		{
			MONITOR_ACTION_POPUP,
			(monitor_popup),
			NULL
		},
		{
			(conf_form_domain_watch),
			NULL
		}
	},

	{
		MONITOR_TYPE_DOS,
		"Denial of Service Monitor",
		"Abnormally high activity thought to be malicious will trigger a notification",
		FALSE,
		-1,
		(watch_init_dos),
		{
			MONITOR_ACTION_POPUP,
			(monitor_popup),
			NULL
		},
		{
			(conf_form_dos),
			NULL		
		}
	},

};
	
short
watch_init_url(w3lclient *w3lc,monitor *m)
{
	char *id;
	
	if(!((m->conf).confData.url))
		return FALSE;
	
	if((id = w3lRequest(w3lc,"watch_url(%s)",(m->conf).confData.url))) {
		m->id = atoi(id);
		m->active = TRUE;
		
		return TRUE;
	}
	
	return FALSE;
}

short
watch_init_domain(w3lclient *w3lc,monitor *m)
{
	char *id;
	
	if(!((m->conf).confData.domain.domain))
		return FALSE;
	
	if((id = w3lRequest(w3lc,"watch_user(%s)",(m->conf).confData.domain.domain))) {
		m->id = atoi(id);
		m->active = TRUE;
		
		return TRUE;
	}
	
	return FALSE;
}

short
watch_init_dos(w3lclient *w3lc,monitor *m)
{
	return FALSE;
}
	
void
monitor_popup(char *msg) {
	gdk_threads_enter();
	{
		gtk_widget_show(create_windowMonitorPopup("time","name",msg));
	}
	gdk_threads_leave();
}


GtkWidget *
conf_form_url_watch(GtkWidget *app, monitor *m)
{
	GtkWidget *table;
	GtkWidget *labelURL;
	GtkWidget *entryURL;
	
	table = gtk_table_new(1,2,FALSE);
	gtk_widget_show(table);
	gtk_container_set_border_width (GTK_CONTAINER (table), 10);
	gtk_table_set_row_spacings (GTK_TABLE (table), 5);
	gtk_table_set_col_spacings (GTK_TABLE (table), 5);
	
	labelURL = gtk_label_new (_("URL:"));
	gtk_widget_show (labelURL);
	gtk_table_attach (GTK_TABLE (table), labelURL, 0, 1, 0, 1,
               	  (GtkAttachOptions) (GTK_FILL),
               	  (GtkAttachOptions) (0), 0, 0);
	gtk_label_set_justify (GTK_LABEL (labelURL), GTK_JUSTIFY_LEFT);
	gtk_misc_set_alignment (GTK_MISC (labelURL), 0, 0.5);
	
	entryURL = gtk_entry_new ();
	gtk_widget_show (entryURL);
	
	if((m->conf).confData.url)
		gtk_entry_set_text(GTK_ENTRY(entryURL),(m->conf).confData.url);
	
	gtk_table_attach (GTK_TABLE (table), entryURL, 1, 2, 0, 1,
               	  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
               	  (GtkAttachOptions) (0), 0, 0);

	g_signal_connect(G_OBJECT(entryURL),"changed",
			G_CALLBACK(monitor_value_gtkentry),
			&((m->conf).confData.url));
	
	GLADE_HOOKUP_OBJECT (app, table, "conftable");
	
	return table;
}

GtkWidget *
conf_form_domain_watch(GtkWidget *app, monitor *m)
{
	GtkWidget *table;
	GtkWidget *labelDomain;
	GtkWidget *entryDomain;
	
	table = gtk_table_new(1,2,FALSE);
	gtk_widget_show(table);
	gtk_container_set_border_width (GTK_CONTAINER (table), 10);
	gtk_table_set_row_spacings (GTK_TABLE (table), 5);
	gtk_table_set_col_spacings (GTK_TABLE (table), 5);
	
	labelDomain = gtk_label_new (_("Domain:"));
	gtk_widget_show (labelDomain);
	
	gtk_table_attach (GTK_TABLE (table), labelDomain, 0, 1, 0, 1,
               	  (GtkAttachOptions) (GTK_FILL),
               	  (GtkAttachOptions) (0), 0, 0);
	gtk_label_set_justify (GTK_LABEL (labelDomain), GTK_JUSTIFY_LEFT);
	gtk_misc_set_alignment (GTK_MISC (labelDomain), 0, 0.5);
	
	entryDomain = gtk_entry_new ();
	gtk_widget_show (entryDomain);
	
	if((m->conf).confData.domain.domain)
		gtk_entry_set_text(GTK_ENTRY(entryDomain),(m->conf).confData.domain.domain);
	
	
	gtk_table_attach (GTK_TABLE (table), entryDomain, 1, 2, 0, 1,
               	  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
               	  (GtkAttachOptions) (0), 0, 0);

	g_signal_connect(G_OBJECT(entryDomain),"changed",
			G_CALLBACK(monitor_value_gtkentry),
			&((m->conf).confData.domain.domain));
	
	GLADE_HOOKUP_OBJECT (app, table, "conftable");
	
	return table;
}

GtkWidget *
conf_form_dos(GtkWidget *app, monitor *m)
{
	GtkWidget *table;
	GtkWidget *labelMDOSThreshold;
	GtkWidget *hscaleMDOSThreshold;
	
	table = gtk_table_new(1,2,FALSE);
	gtk_widget_show(table);
	gtk_container_set_border_width (GTK_CONTAINER (table), 10);
	gtk_table_set_row_spacings (GTK_TABLE (table), 5);
	gtk_table_set_col_spacings (GTK_TABLE (table), 5);

	
	labelMDOSThreshold = gtk_label_new (_("Abnormality\nThreshold:"));
	gtk_widget_show (labelMDOSThreshold);
	gtk_table_attach (GTK_TABLE (table), labelMDOSThreshold, 0, 1, 0, 1,
               	  (GtkAttachOptions) (GTK_FILL),
               	  (GtkAttachOptions) (0), 0, 0);
	gtk_label_set_justify (GTK_LABEL (labelMDOSThreshold), GTK_JUSTIFY_LEFT);
	gtk_misc_set_alignment (GTK_MISC (labelMDOSThreshold), 0, 0.5);
	
	
	hscaleMDOSThreshold = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0.5, 0, 1, 0.01, 0.1, 0.1)));
	gtk_widget_show (hscaleMDOSThreshold);
	gtk_table_attach (GTK_TABLE (table), hscaleMDOSThreshold, 1, 2, 0, 1,
               	  (GtkAttachOptions) (GTK_FILL),
               	  (GtkAttachOptions) (GTK_FILL), 0, 0);
	gtk_widget_set_usize (hscaleMDOSThreshold, 200, -2);
	gtk_scale_set_digits (GTK_SCALE (hscaleMDOSThreshold), 2);
	gtk_range_set_update_policy (GTK_RANGE (hscaleMDOSThreshold), GTK_UPDATE_DELAYED);


	GLADE_HOOKUP_OBJECT (app, table, "conftable");
	
	return table;
}

void 
monitor_value_gtkentry(GtkEntry *entry, char **value)
{
	char *text;
	if(!(text = (char *)gtk_entry_get_text(GTK_ENTRY(entry))))
		return;
	if(*value)
		free(*value);
	*value = strdup(text);
}




void
updateMonitors(w3lclient *w3lc)
{
	int i;
	monitor *m;
	char *reply;
	
	for(i=0;i<MONITOR_TYPE_COUNT;i++) {
		m = &(monitors[i]);
		if(m->active) {
			reply = w3lRequest(w3lc,"check_watch(%d)",m->id);

			if(strlen(reply)>0)
				((m->action).handler)(reply);
		}
	}	
}
